/*
 * Base64Image Plugin for CKEditor (http://github.com/nmmf/base64image)
 * Created by ALL-INKL.COM - Neue Medien M�nnich - 04. Feb 2014
 * Licensed under the terms of GPL, LGPL and MPL licenses.
 */

CKEDITOR.plugins.base64image = {
    defaultConfig: {
        maxFileSize: 024 * 700,
        upload: false
    }
};

CKEDITOR.plugins.add("base64image", {
    lang: ["af", "ar", "bg", "bn", "bs", "ca", "cs", "cy", "da", "de", "el", "en", "en-au", "en-ca", "en-gb", "eo", "es", "et", "eu", "fa", "fi", "fo", "fr", "fr-ca", "gl", "gu", "he", "hi", "hr", "hu", "id", "is", "it", "ja", "ka", "km", "ko", "ku", "lt", "lv", "mk", "mn", "ms", "nb", "nl", "no", "pl", "pt", "pt-br", "ro", "ru", "si", "sk", "sl", "sq", "sr", "sr-latn", "sv", "th", "tr", "ug", "uk", "vi", "zh", "zh-cn"],
    requires: "dialog",
    icons: "base64image",
    hidpi: true,
    init: function (editor) {
        var pluginName = 'base64imageDialog';
        editor.ui.addButton("base64image", {
            //label: editor.lang.common.image,
            label: editor.lang.base64image.image,
            command: pluginName,
            toolbar: "insert"
        });

        editor.on('contentDom', function () {
            editor.document.$.body.onpaste = function (e) {
                "use strict";
                var env = CKEDITOR.env,
                    config = CKEDITOR.tools.extend(editor.config.base64image, CKEDITOR.plugins.base64image.defaultConfig),
                    currentHtml = this.innerHTML, PASTE_SIGN = 'oldPastedImage';
                function setStatusBarInfo(info) {
                    if (!config.statusBar) return false;
                    var statusBar = document.getElementById(config.statusBar);
                    if (!statusBar)return false;
                    statusBar.innerHTML = info;
                    return statusBar;
                }

                setStatusBarInfo("");

                function dataURIToBlob(dataURI) {
                    // convert base64 to raw binary data held in a string
                    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
                    var tokens = dataURI.split(','), preData = tokens[0], data = tokens[1];

                    var byteString = preData.indexOf('base64') >= 0 ? atob(data) : decodeURIComponent(data);
                    // separate out the mime component
                    var mimeString = preData.split(':')[1].split(';')[0];

                    // write the bytes of the string to an ArrayBuffer
                    var binArray = [];
                    for (var i = 0; i < byteString.length; i++) {
                        binArray.push(byteString.charCodeAt(i));
                    }
                    return new Blob([new Uint8Array(binArray)], {type: mimeString});
                }

                function findLastPastedImage(pasteSign){
                    pasteSign = pasteSign || PASTE_SIGN;
                    var images = editor.document.$.getElementsByTagName("img"), pastedImage = null;
                    for(var i=0; i<images.length; ++i){
                        var image = images[i];
                        var sign = image.getAttribute(pasteSign);
                        if(!sign) return image;
                    }
                    return null;
                }

                function checkFireFoxImage(me) {
                    setTimeout(function () {
                        if (currentHtml === editor.document.$.body.innerHTML) {
                            checkFireFoxImage(me);
                        } else {
                          var pastedImage = findLastPastedImage();
                            if(!pastedImage){
                                setStatusBarInfo("Did not find any pasted image!");
                                return;
                            }
                            var dataURI = pastedImage.src;
                            if (config.upload && editor.config.filebrowserImageUploadUrl) {
                                uploadBlob(dataURIToBlob(dataURI), function (json) {
                                    pastedImage.src = json.uploadedFilePath;
                                    pastedImage.setAttribute('data-cke-saved-src', json.uploadedFilePath);
                                    pastedImage.setAttribute(PASTE_SIGN, true);
                                });
                            }
                        }
                    }, 20);
                }

                function uploadBlob(blob, callback) {
                    var xhr = new XMLHttpRequest(), formData = new FormData();
                    xhr.onload = function (e) {
                        if (e.target.status == 200 && e.target.responseText) {
                            //console.log(xhr.responseText);
                            var json = JSON.parse(xhr.responseText);
                            if (0 != json.status) {
                                alert("Upload image file failure: " + json.message);
                                return false;
                            }
                            if ('function' === typeof callback) {
                                var serverFilePostName = 'cke-saved-src', msg = json.message,
                                    index = msg.indexOf(serverFilePostName) + serverFilePostName.length + 1,
                                    uploadedFilePath = msg.substring(index);
                                setStatusBarInfo("File uploaded to: " + uploadedFilePath);
                                callback.call(blob, {status: json.status, uploadedFilePath: uploadedFilePath});
                            }
                        }
                    };
                    xhr.onprogress = function (e) {
                        var percentage = (e.loaded / e.total) * 100,
                            info = "Uploading " + percentage + '%' + ' ' + Array(Math.floor(percentage)).join('.');
                        setStatusBarInfo(info);
                    };


                    var fileName = 'Image' + new Date().getTime() + '.' + blob.type.split('/')[1];
                    formData.append('upload', blob, fileName);

                    xhr.open('POST', editor.config.filebrowserImageUploadUrl, true);
                    xhr.send(formData);
                }

                /**
                 * Find image in clipboardData for IE10(version>10) or webkit browser
                 *
                 * */
                function handleImageInCollection(clipboardData, isWebkit) {
                    /**
                     * The files have type, name, and size property
                     * For example,type: "image/png"
                     * */
                    var items = isWebkit ? clipboardData.items : clipboardData.files;
                    if (!items)return null;
                    for (var index = 0; index < items.length; index++) {
                        var item = items[index];
                        if (!item.type.match(/image.*/i)) continue;
                        var file = isWebkit ? item.getAsFile() : item, reader = new FileReader();
                        reader.onload = function (e) {
                            var dataURI = e.target.result;
                            console.log("dataURI=%o", file, dataURI);
                            if (config.upload && editor.config.filebrowserImageUploadUrl) {
                                var blob = dataURIToBlob(dataURI);
                                uploadBlob(blob, function (json) {
                                    //console.log("json=", json);
                                    if (isWebkit) {
                                        var element = CKEDITOR.dom.element.createFromHtml('<img src="' + json.uploadedFilePath
                                        + '" data-cke-saved-src="' + json.uploadedFilePath + '" />');
                                        editor.insertElement(element);
                                    } else {
                                        var pastedImage = findLastPastedImage();
                                        if(!pastedImage){
                                            setStatusBarInfo("Did not find any pasted image!");
                                            return false;
                                        }
                                        pastedImage.src = json.uploadedFilePath;
                                        pastedImage.setAttribute('data-cke-saved-src', json.uploadedFilePath);
                                        pastedImage.setAttribute(PASTE_SIGN, true);
                                    }
                                });
                            } else if (isWebkit) {
                                var element = CKEDITOR.dom.element.createFromHtml('<img src="' + dataURI + '"/>');
                                editor.insertElement(element);
                            }
                        };
                        reader.readAsDataURL(file);
                        break;
                    }
                }

                if (env.webkit) {
                    handleImageInCollection(e.clipboardData, true);
                } else if (env.ie) { // for IE
                    if(env.version > 9){
                        handleImageInCollection(window.clipboardData);
                    }else{
                        setStatusBarInfo("Your browser is not support copy & past image, please update to IE10 or later version.")
                    }

                } else if (env.gecko) {    //firefox product
                    checkFireFoxImage();
                }
            }
        });

        CKEDITOR.dialog.add(pluginName, this.path + "dialogs/base64image.js");

        var allowed = 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}',
            required = 'img[alt,src]';

        editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName, {
            allowedContent: allowed,
            requiredContent: required,
            contentTransformations: [
                ['img{width}: sizeToStyle', 'img[width]: sizeToAttribute'],
                ['img{float}: alignmentToStyle', 'img[align]: alignmentToAttribute']
            ]
        }));

        editor.on("doubleclick", function (evt) {
            if (evt.data.element && !evt.data.element.isReadOnly() && evt.data.element.getName() === "img") {
                evt.data.dialog = pluginName;
                editor.getSelection().selectElement(evt.data.element);
            }
        });
        if (editor.addMenuItem) {
            editor.addMenuGroup("base64imageGroup");
            editor.addMenuItem("base64imageItem", {
                label: editor.lang.common.image,
                icon: this.path + "icons/base64image.png",
                command: pluginName,
                group: "base64imageGroup"
            });
        }
        if (editor.contextMenu) {
            editor.contextMenu.addListener(function (element, selection) {
                if (element && element.getName() === "img") {
                    editor.getSelection().selectElement(element);
                    return {base64imageItem: CKEDITOR.TRISTATE_ON};
                }
                return null;
            });
        }
    }
});
